import type {AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse} from "axios";
import axios from "axios";
import {ResultEnum} from "@/enums/httpEnums";
import {useUserStore, useUserStoreWithOut} from "@/stores/modules/user";
import {ElMessage} from "element-plus";
import {RESETSTORE} from "@/utils/reset";
import router from "@/router";
import {LOGIN_URL} from "@/config/config";
import type {ResultData} from "@/utils/http/type";

const service: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_API,
    timeout: ResultEnum.TIMEOUT as number,
})

/**
 * @description: 请求拦截器
 * @return {*}
 */
service.interceptors.request.use(
    (config) => {
    const userStore = useUserStoreWithOut();
    const token = userStore.token;
    if (token){
        config.headers.token = token
    }
    return config

},
    (error: AxiosError) =>{
    ElMessage.error(error.message);
    return Promise.reject(error)
})

service.interceptors.response.use(
    (response: AxiosResponse) => {
        const { data } = response;
        if (data.code === ResultEnum.EXPIRE) {
            RESETSTORE();
            ElMessage.error(data.message || ResultEnum.ERRMESSAGE);
            router.replace(LOGIN_URL)
            return Promise.reject(data)
        }

        if (data.code && data.code !== ResultEnum.SUCCESS) {
            ElMessage.error(data.message || ResultEnum.ERRMESSAGE)
        }
        return data;
    },
    ( error: AxiosError) => {
        // 处理 http错误
        let message = '';
        const  status = error.response?.status
        switch (status){
            case 401:
                message = 'token 失效，请重新登录'
                break
            case 403:
                message = '拒绝访问'
                break
            case 404:
                message = '请求地址错误'
                break
            case 500:
                message = '服务器故障'
                break
            default:
                message = '网络连接故障'
        }
        ElMessage.error(message)
        return Promise.reject(error)
    }
)
/**
 * 导出封装的请求方法
 */
const http = {
     get<T>(url: string,
            params?: object,
            config?: AxiosRequestConfig
     ): Promise<ResultData<T>>{
         return service.get(url, {params, ...config});
     },
    post<T>(url: string,
           data?: object,
           config?: AxiosRequestConfig
    ): Promise<ResultData<T>>{
        return service.post(url, data, config);
    },
    put<T>(url: string,
           data?: object,
           config?: AxiosRequestConfig
    ): Promise<ResultData<T>>{
        return service.put(url, data, config);
    },
    delete<T>(url: string,
           data?: object,
           config?: AxiosRequestConfig
    ): Promise<ResultData<T>>{
        return service.delete(url, {data, ...config});
    },
}

export default http;